/*******************************************************************************
MPLAB Harmony Application Source File

Company:
Microchip Technology Inc.

File Name:
app.c

Summary:
This file contains the source code for the MPLAB Harmony application.

Description:
This file contains the source code for the MPLAB Harmony application. It
implements the logic of the application's state machine and it may call
API routines of other MPLAB Harmony modules in the system, such as drivers,
system services, and middleware. However, it does not call any of the
system interfaces (such as the "Initialize" and "Tasks" functions) of any of
the modules in the system or make any assumptions about when those functions
are called. That is the responsibility of the configuration-specific system
files.
*******************************************************************************/

// DOM-IGNORE-BEGIN
/*******************************************************************************
Copyright (c) 2013-2014 released Microchip Technology Inc. All rights reserved.

Microchip licenses to you the right to use, modify, copy and distribute
Software only when embedded on a Microchip microcontroller or digital signal
controller that is integrated into your product or third party product
(pursuant to the sublicense terms in the accompanying license agreement).

You should refer to the license agreement accompanying this Software for
additional information regarding your rights and obligations.

SOFTWARE AND DOCUMENTATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF
MERCHANTABILITY, TITLE, NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE.
IN NO EVENT SHALL MICROCHIP OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER
CONTRACT, NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR
OTHER LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE OR
CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT OF
SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
(INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
*******************************************************************************/
// DOM-IGNORE-END


// *****************************************************************************
// *****************************************************************************
// Section: Included Files
// *****************************************************************************
// *****************************************************************************

#include "app.h"


//対象キーボード: 日本語106/109キーボード

#include "stdio.h"


char Buf[32];
char strUART[16];
char moji_Esc[] = "Esc";
char moji_Tab[] = "Tab";
char moji_Enter[] = "Enter";
char moji_BackSpace[] = "Back Space";
char moji_CapsLock[] = "Caps Lock";
char moji_PrintScreen[] = "PrintScreen"; //Max11文字(UART送信側制約)
char moji_ScrollLock[] = "Scroll Lock";
char moji_PauseBreak[] = "Pause Break";
char moji_Insert[] = "Insert";
char moji_PageUp[] = "Page Up";
char moji_Delete[] = "Delete";
char moji_End[] = "End";
char moji_Home[] = "Home";
char moji_PageDown[] = "Page Down";
char moji_ArrowRight[] = "Arrow Right";
char moji_ArrowLeft[] = "Arrow Left";
char moji_ArrowDown[] = "Arrow Down";
char moji_ArrowUp[] = "Arrow Up";
char moji_NumLock[] = "Num Lock";
char moji_Kanji[] = "Kanji";
char moji_MuHenkan[] = "MuHenkan";
char moji_Henkan[] = "Henkan";
char moji_Katakana[] = "Katakana";
char moji_Menu[] = "Menu";
char moji_F1[] = "F1";
char moji_F2[] = "F2";
char moji_F3[] = "F3";
char moji_F4[] = "F4";
char moji_F5[] = "F5";
char moji_F6[] = "F6";
char moji_F7[] = "F7";
char moji_F8[] = "F8";
char moji_F9[] = "F9";
char moji_F10[] = "F10";
char moji_F11[] = "F11";
char moji_F12[] = "F12";
char moji_10keyEnter[] = "10key Enter";


int delay_Clock = 200000000; //200MHz

void delay_us(volatile unsigned int usec) //1μsec遅延
{
volatile int count;

count = (int)(delay_Clock/20000000)*usec;
do //実測 at 200MH (Clock=200000000)
{ //delay_us(1000):1000.4μsec delay_us(100):100.6μsec delay_us(10):10.5μsec  delay_us(1):1.5μsec
asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");asm("NOP");
asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP"); asm("NOP");

count--;
}while(count != 0);
}

void delay_ms(volatile unsigned int msec) //1msec遅延
{
volatile unsigned int i; //実測:at200MH (Clock=200000000)//delay_ms(1): 1.0006msec delay_ms(100):100.04msec

for(i=0; i<msec; i++)
delay_us(1000);
}



// *****************************************************************************
// *****************************************************************************
// Section: Global Data Definitions
// *****************************************************************************
// *****************************************************************************

/* Usage ID to Key map table */
const char *keyValue[] = {
//メインキー + ファンクションキー 部分 ------------------------------------------------------------------------
// keycodeの値
// 10進数表示 16進数表示
"No event indicated", //0 //0x00
"ErrorRoll Over", //1 //0x01
"POSTFail", //2 //0x02
"Error Undefined", //3 //0x03
"a", //4 //0x04
"b", //5 //0x05
"c", //6 //0x06
"d", //7 //0x07
"e", //8 //0x08
"f", //9 //0x09
"g", //10 //0x0A
"h", //11 //0x0B
"i", //12 //0x0C
"j", //13 //0x0D
"k", //14 //0x0E
"l", //15 //0x0F
"m", //16 //0x10
"n", //17 //0x11
"o", //18 //0x12
"p", //19 //0x13
"q", //20 //0x14
"r", //21 //0x15
"s", //22 //0x16
"t", //23 //0x17
"u", //24 //0x18
"v", //25 //0x19
"w", //26 //0x1A
"x", //27 //0x1B
"y", //28 //0x1C
"z", //29 //0x1D
"1", //30 //0x1E
"2", //31 //0x1F
"3", //32 //0x20
"4", //33 //0x21
"5", //34 //0x22
"6", //35 //0x23
"7", //36 //0x24
"8", //37 //0x25
"9", //38 //0x26
"0", //39 //0x27
"ENTER", //40 //0x28
"ESCAPE", //41 //0x29
"BACKSPACE", //42 //0x2A
"TAB", //43 //0x2B
"SPACEBAR", //44 //0x2C
"-", //45 //0x2D
"=", //46 //0x2E // "^キー" at 日本語106/109キーボード
"[", //47 //0x2F // "@キー" at 日本語106/109キーボード
"]", //48 //0x30 // "[キー" at 日本語106/109キーボード
"\\0", //49 //0x31
"~", //50 //0x32 // "]キー" at 日本語106/109キーボード
";", //51 //0x33
"'", //52 //0x34 // ":キー" at 日本語106/109キーボード
"GRAVE ACCENT", //53 //0x35 //"半角/全角 漢字キー" at 日本語106/109キーボード
",", //54 //0x36
".", //55 //0x37
"/", //56 //0x38
"CAPS LOCK", //57 //0x39
"F1", //58 //0x3A
"F2", //59 //0x3B
"F3", //60 //0x3C
"F4", //61 //0x3D
"F5", //62 //0x3E
"F6", //63 //0x3F
"F7", //64 //0x40
"F8", //65 //0x41
"F9", //66 //0x42
"F10", //67 //0x43
"F11", //68 //0x44
"F12" //69 //0x45


// "Print Screen" //70 //0x46
// "Scroll Lock" //71 //0x47
// "Pause/Break" //72 //0x48
// "Insert" //73 //0x49
// "home" //74 //0x4A
// "Page Up" //75 //0x4B
// "delete" //76 //0x4C
// "end" //77 //0x4D
// "Page Down" //78 //0x4E
// "Right Arrow" //79 //0x4F
// "Left Arrow" //80 //0x50
// "Down Arrow" //81 //0x51
// "Up Arrow" //82 //0x52
// "Num Lock" //83 //0x53
// "LEFT ALT" //226 //0xE2 //Reserved //keyCodeでは呼び出せない(at Harmony 2.04)
// "RIGHT ALT" //230 //0xE6 //Reserved //keyCodeでは呼び出せない(at Harmony 2.04)
// "UNDER BAR" //4294967175 //0xFFFFFF87
// "カタカナ" //4294967176 //0xFFFFFF88
// "\" //4294967177 //0xFFFFFF89
// "変換" //4294967178 //0xFFFFFF8A
// "無変換" //4294967179 //0xFFFFFF8B
// "Windows(右)" //keyCode 設定なし
// "Windows(左)" //keyCode 設定なし
// "Menu" //101 //0x65
// "Shift(右)" //keyCode 設定なし
// "Shift(左)" //keyCode 設定なし
// "Ctrl(右)" //KeyCode 設定なし
// "Ctrl(左)" //KeyCode 設定なし
// "Alt(右)" //KeyCode 設定なし
// "Alt(左)" //KeyCode 設定なし

// テンキー 部分 ---------------------------------------------------------------------------------------
// "/_keypad" //84 //0x54
// "*_keypad" //85 //0x55
// "-_keypad" //86 //0x56
// "+_keypad" //87 //0x57
// "Enter" //88 //0x58
// "1_keypad" //89 //0x59
// "2_keypad" //90 //0x5A
// "3_keypad" //91 //0x5B
// "4_keypad" //92 //0x5C
// "5_keypad" //93 //0x5D
// "6_keypad" //94 //0x5E
// "7_keypad" //95 //0x5F
// "8_keypad" //96 //0x60
// "9_keypad" //97 //0x61
// "0_keypad" //98 //0x62
// "._keypad" //99 //0x63

// テンキー部分(シフトの場合) → 未対応(シフトなしと全部同じ)

};

// *****************************************************************************
/* Application Data

Summary:
Holds application data

Description:
This structure holds the application's data.

Remarks:
This structure should be initialized by the APP_Initialize function.

Application strings and buffers are be defined outside this structure.
*/

APP_DATA appData;


// *****************************************************************************
// *****************************************************************************
// Section: Application Local Routines
// *****************************************************************************


// *****************************************************************************
// *****************************************************************************
// Section: Application Callback Functions
// *****************************************************************************
// *****************************************************************************

/*******************************************************
* USB HOST Layer Events - Host Event Handler
*******************************************************/

USB_HOST_EVENT_RESPONSE APP_USBHostEventHandler (USB_HOST_EVENT event, void * eventData, uintptr_t context)
{
switch(event)
{
case USB_HOST_EVENT_DEVICE_UNSUPPORTED:
break;
default:
break;
}
return USB_HOST_EVENT_RESPONSE_NONE;
}

/*******************************************************
* USB HOST HID Layer Events - Application Event Handler
*******************************************************/

void APP_USBHostHIDKeyboardEventHandler(USB_HOST_HID_KEYBOARD_HANDLE handle,
USB_HOST_HID_KEYBOARD_EVENT event, void * pData)
{
switch ( event)
{
case USB_HOST_HID_KEYBOARD_EVENT_ATTACH:
appData.handle = handle;
appData.state = APP_STATE_DEVICE_ATTACHED;
appData.nBytesWritten = 0;
appData.stringReady = false;
memset(&appData.string, 0, sizeof(appData.string));
memset(&appData.lastData, 0, sizeof(appData.lastData));
appData.stringSize = 0;
appData.capsLockPressed = false;
appData.scrollLockPressed = false;
appData.numLockPressed = false;
appData.outputReport = 0;
break;

case USB_HOST_HID_KEYBOARD_EVENT_DETACH:
appData.handle = handle;
appData.state = APP_STATE_DEVICE_DETACHED;
appData.nBytesWritten = 0;
appData.stringReady = false;
appData.usartTaskState = APP_USART_STATE_CHECK_FOR_STRING_TO_SEND;
memset(&appData.string, 0, sizeof(appData.string));
memset(&appData.lastData, 0, sizeof(appData.lastData));
appData.stringSize = 0;
appData.capsLockPressed = false;
appData.scrollLockPressed = false;
appData.numLockPressed = false;
appData.outputReport = 0;
break;

case USB_HOST_HID_KEYBOARD_EVENT_REPORT_RECEIVED:
appData.handle = handle;
appData.state = APP_STATE_READ_HID;
/* Keyboard Data from device */
memcpy(&appData.data, pData, sizeof(appData.data));
break;

default:
break;
}
return;
}


// *****************************************************************************
// *****************************************************************************
// Section: Application Local Functions
// *****************************************************************************
// *****************************************************************************

/* TODO: Add any necessary local functions.
*/

void ys_Char(USB_HID_KEYBOARD_KEYPAD _keyCode) //英数文字キー
{
//I2Cキャラクタ液晶表示
lcd_ACM1602_cmd_i2c(0x80); //1行目の先頭へ
sprintf(Buf,"key=0x%02X ",_keyCode);
lcd_ACM1602_str_i2c(Buf);

lcd_ACM1602_cmd_i2c(0xC0); //2行目の先頭へ
sprintf(Buf,"%c ",appData.string[appData.currentOffset]);
lcd_ACM1602_str_i2c(Buf);
}


void ys_Char_0xXX(USB_HID_KEYBOARD_KEYPAD _keyCode, char myChar) //一般記号文字キー
{
appData.string[appData.currentOffset] = myChar; //UART出力へ

//I2Cキャラクタ液晶表示
lcd_ACM1602_cmd_i2c(0x80); //1行目の先頭へ
sprintf(Buf,"key=0x%02X ",_keyCode);
lcd_ACM1602_str_i2c(Buf);

lcd_ACM1602_cmd_i2c(0xC0); //2行目の先頭へ
sprintf(Buf,"%c ",appData.string[appData.currentOffset]);
lcd_ACM1602_str_i2c(Buf);
}

void ys_Char_0xFFFF(USB_HID_KEYBOARD_KEYPAD _keyCode, char myChar) //特別扱い文字キー:  \ _
{
appData.string[appData.currentOffset] = myChar; //UART出力へ

//I2Cキャラクタ液晶表示
lcd_ACM1602_cmd_i2c(0x80); //1行目の先頭へ
sprintf(Buf,"key=0x%X ",_keyCode);
lcd_ACM1602_str_i2c(Buf);

lcd_ACM1602_cmd_i2c(0xC0); //2行目の先頭へ
sprintf(Buf,"%c ",appData.string[appData.currentOffset]);//
lcd_ACM1602_str_i2c(Buf);
}

void ys_Function_Enter(USB_HID_KEYBOARD_KEYPAD _keyCode) //エンターキー
{
memcpy(&appData.string[appData.currentOffset], "\r\n", strlen("\r\n")); //UART出力へ

//I2Cキャラクタ液晶表示
lcd_ACM1602_cmd_i2c(0x80); //1行目の先頭へ
sprintf(Buf,"key=0x%02X ",_keyCode); //キーコードを16進数で表示
lcd_ACM1602_str_i2c(Buf);

lcd_ACM1602_cmd_i2c(0xC0); //2行目の先頭へ
sprintf(Buf,"Enter ");
lcd_ACM1602_str_i2c(Buf);
}

void ys_Function_0xXX(USB_HID_KEYBOARD_KEYPAD _keyCode, char* str0) //一般機能キー
{
strcpy(strUART,"\r\n");
strncat(strUART, str0, strlen(str0)); //UART出力: 文字列出力前に改行(\r\n)
memcpy(&appData.string[appData.currentOffset], strUART, strlen(strUART)); //UART出力へ

//I2Cキャラクタ液晶表示
lcd_ACM1602_cmd_i2c(0x80); //1行目の先頭へ
sprintf(Buf,"key=0x%02X ",_keyCode); //キーコードを16進数で表示
lcd_ACM1602_str_i2c(Buf);

lcd_ACM1602_cmd_i2c(0xC0); //2行目の先頭へ
sprintf(Buf,"%s ",str0);
lcd_ACM1602_str_i2c(Buf);
}

void ys_Function_0xFFFF(USB_HID_KEYBOARD_KEYPAD _keyCode, char* str0) //特別扱い機能キー //"カタカナ" "変換" "無変換"
{
strcpy(strUART,"\r\n");
strncat(strUART, str0, strlen(str0)); //UART出力: 文字列出力前に改行(\r\n)
memcpy(&appData.string[appData.currentOffset], strUART, strlen(strUART)); //UART出力へ

//I2Cキャラクタ液晶表示
lcd_ACM1602_cmd_i2c(0x80); //1行目の先頭へ
sprintf(Buf,"key=0x%X ",_keyCode); //キーコードを16進数で表示
lcd_ACM1602_str_i2c(Buf);

lcd_ACM1602_cmd_i2c(0xC0); //2行目の先頭へ
sprintf(Buf,"%s ",str0);
lcd_ACM1602_str_i2c(Buf);
}

void ys_NonShift_MapKey(USB_HID_KEYBOARD_KEYPAD keyCode, uint8_t outputReport) //非シフトモードのキーマップ関数
{
//keyCodeの対応文字が a,b,c,...x,y,z, 1,2,...,8,9,0 の場合
if((keyCode >= USB_HID_KEYBOARD_KEYPAD_KEYBOARD_A) && // a,b,c,...x,y,z, 1,2,...,8,9,0
(keyCode <= USB_HID_KEYBOARD_KEYPAD_KEYBOARD_0_AND_CLOSE_PARENTHESIS)) //0x04 <= keyCode <= 0x27
{
memcpy(&appData.string[appData.currentOffset], keyValue[keyCode], strlen(keyValue[keyCode]));
ys_Char(keyCode); //キャラクタ液晶表示
}

//keyCode判別
switch(keyCode)
{
case 0x2D: //Minus -
ys_Char_0xXX(keyCode, '-'); break;
case 0x2E: //Carrot ^
ys_Char_0xXX(keyCode, '^'); break;
case 0xFFFFFF89: //円 \
ys_Char_0xFFFF(keyCode, '\\'); break;
case 0x2F: //アットマーク @
ys_Char_0xXX(keyCode, '@'); break;
case 0x30 : //オープン大括弧 [
ys_Char_0xXX(keyCode, '['); break;
case 0x33: //セミコロン ;
ys_Char_0xXX(keyCode, ';'); break;
case 0x34: //コロン :
ys_Char_0xXX(keyCode, ':'); break;
case 0x32: //クローズ大括弧 ]
ys_Char_0xXX(keyCode, ']'); break;
case 0x36: //カンマ ,
ys_Char_0xXX(keyCode, ','); break;
case 0x37: //ピリオド .
ys_Char_0xXX(keyCode, '.'); break;
case 0x38: //スラッシュ /
ys_Char_0xXX(keyCode, '/'); break;
case 0xFFFFFF87: //アンダーバー _
ys_Char_0xFFFF(keyCode, '\\'); break;
case USB_HID_KEYBOARD_KEYPAD_KEYBOARD_TAB: //0x28 //タブ Tab
ys_Function_0xXX(keyCode, moji_Tab); break;
case USB_HID_KEYBOARD_KEYPAD_KEYPAD_BACK_SLASH: //0x54 //テンキー スラッシュ /
ys_Char_0xXX(keyCode, '/'); break;
case USB_HID_KEYBOARD_KEYPAD_KEYPAD_ASTERISK: //0x55 //テンキー アスタリスク *
ys_Char_0xXX(keyCode, '*'); break;
case USB_HID_KEYBOARD_KEYPAD_KEYPAD_MINUS: //0x56 //テンキー マイナス -
ys_Char_0xXX(keyCode, '-'); break;
case USB_HID_KEYBOARD_KEYPAD_KEYPAD_PLUS: //0x57 //テンキー プラス +
ys_Char_0xXX(keyCode, '+'); break;
case USB_HID_KEYBOARD_KEYPAD_KEYPAD_ENTER: //0x58 //テンキーエンター Enter
ys_Function_0xXX(keyCode, moji_10keyEnter); break;
case USB_HID_KEYBOARD_KEYPAD_KEYPAD_1_AND_END: //0x59 //テンキー1 1
ys_Char_0xXX(keyCode, '1'); break;
case USB_HID_KEYBOARD_KEYPAD_KEYPAD_2_AND_DOWN_ARROW: //0x5A //テンキー2 2
ys_Char_0xXX(keyCode, '2'); break;
case USB_HID_KEYBOARD_KEYPAD_KEYPAD_3_AND_PAGE_DOWN: //0x5B //テンキー3 3
ys_Char_0xXX(keyCode, '3'); break;
case USB_HID_KEYBOARD_KEYPAD_KEYPAD_4_AND_LEFT_ARROW: //0x5C //テンキー4 4
ys_Char_0xXX(keyCode, '4'); break;
case USB_HID_KEYBOARD_KEYPAD_KEYPAD_5: //0x5D //テンキー5 5
ys_Char_0xXX(keyCode, '5'); break;
case USB_HID_KEYBOARD_KEYPAD_KEYPAD_6_AND_RIGHT_ARROW: //0x5E //テンキー6 6
ys_Char_0xXX(keyCode, '6'); break;
case USB_HID_KEYBOARD_KEYPAD_KEYPAD_7_AND_HOME: //0x5F //テンキー7 7
ys_Char_0xXX(keyCode, '7'); break;
case USB_HID_KEYBOARD_KEYPAD_KEYPAD_8_AND_UP_ARROW: //0x60 //テンキー8 8
ys_Char_0xXX(keyCode, '8'); break;
case USB_HID_KEYBOARD_KEYPAD_KEYPAD_9_AND_PAGE_UP: //0x61 //テンキー9 9
ys_Char_0xXX(keyCode, '9'); break;
case USB_HID_KEYBOARD_KEYPAD_KEYPAD_0_AND_INSERT: //0x62 //テンキー0 0
ys_Char_0xXX(keyCode, '0'); break;
case USB_HID_KEYBOARD_KEYPAD_KEYPAD_PERIOD_AND_DELETE: //0x63 //テンキーピリオド .
ys_Char_0xXX(keyCode, '.'); break;
default: break;
}


}

void ys_Shift_MapKey(USB_HID_KEYBOARD_KEYPAD keyCode, uint8_t outputReport) //シフトモードのキーマップ関数
{
//keyCodeの対応文字が a,b,c,...x,y,z の場合
if((keyCode >= USB_HID_KEYBOARD_KEYPAD_KEYBOARD_A) && // a,b,c,...x,y,z
(keyCode <= USB_HID_KEYBOARD_KEYPAD_KEYBOARD_Z)) //0x04 <= keyCode <= 0x1D
{
memcpy(&appData.string[appData.currentOffset], keyValue[keyCode], strlen(keyValue[keyCode]));
appData.string[appData.currentOffset] = appData.string[appData.currentOffset] - 32;
ys_Char(keyCode); //キャラクタ液晶表示
}

//keyCodeの対応文字が !,",#,$,%,&,',(,) の場合
if((keyCode >= USB_HID_KEYBOARD_KEYPAD_KEYBOARD_1_AND_EXCLAMATION_POINT) && //!,",#,$,%,&,',(,)
(keyCode <= USB_HID_KEYBOARD_KEYPAD_KEYBOARD_9_AND_OPEN_PARENTHESIS)) //0x1E <= keyCode <= 0x26
{
memcpy(&appData.string[appData.currentOffset], keyValue[keyCode], strlen(keyValue[keyCode]));
appData.string[appData.currentOffset] = appData.string[appData.currentOffset] - 16;
ys_Char(keyCode); //キャラクタ液晶表示
}

//keyCode判別
switch(keyCode)
{
case 0x2D: //キー: MINUS - //シフト後:EQUAL =
ys_Char_0xXX(keyCode, '='); break;
case 0x2E: //キー: Carrot ^ //シフト後:TILDE ~
ys_Char_0xXX(keyCode, '~'); break;
case 0xFFFFFF89: //キー:円 \ //シフト後:PIPE |
ys_Char_0xFFFF(keyCode, '|'); break;
case 0x2F: //キー:アットマーク @ //シフト後:GRAVE ACCENT `
ys_Char_0xXX(keyCode, '`'); break;
case 0x30 : //キー:オープン大括弧 [ //シフト後: オープン中括弧 {
ys_Char_0xXX(keyCode, '{'); break;
case 0x33: //キー:セミコロン ; //シフト後:プラス +
ys_Char_0xXX(keyCode, '+'); break;
case 0x34: //キー:コロン : //シフト後:アスタリスク *
ys_Char_0xXX(keyCode, '*'); break;
case 0x32: //キー:クローズ大括弧 ] //シフト後:クローズ中括弧 }
ys_Char_0xXX(keyCode, '}'); break;
case 0x36: //キー:カンマ , //シフト後: 小(しょう)なり <
ys_Char_0xXX(keyCode, '<'); break;
case 0x37: //キー:ピリオド . //シフト後: 大(だい)なり >
ys_Char_0xXX(keyCode, '>'); break;
case 0x38: //キー:スラッシュ / //シフト後: 疑問符 ?
ys_Char_0xXX(keyCode, '?'); break;
case 0xFFFFFF87: //キー:アンダーバー_ //シフト後:アンダーバー _
ys_Char_0xFFFF(keyCode, '_'); break;
default: break;
}
}


void APP_MapKeyToUsage(USB_HID_KEYBOARD_KEYPAD keyCode) //keyCode: 打鍵キーコード
{
uint8_t outputReport = 0;

outputReport = appData.outputReport;

if(keyCode == USB_HID_KEYBOARD_KEYPAD_KEYBOARD_CAPS_LOCK)
{
/* CAPS LOCK pressed */
if(appData.capsLockPressed == false) //CAPS_LOCK反転
{
appData.capsLockPressed = true;
outputReport = outputReport | 0x2; //b1 = 1 にセット
}
else
{
appData.capsLockPressed = false;
outputReport = outputReport & 0xFD; //b1 = 0 にリセット
}
}

if(keyCode == USB_HID_KEYBOARD_KEYPAD_KEYBOARD_SCROLL_LOCK)
{
/* SCROLL LOCK pressed */ //SCROLL_LOCK反転
if(appData.scrollLockPressed == false)
{
appData.scrollLockPressed = true;
outputReport = outputReport | 0x4; //b3 = 1 にセット
}
else
{
appData.scrollLockPressed = false;
outputReport = outputReport & 0xFB; //b3 = 0 にリセット
}
}

if(keyCode == USB_HID_KEYBOARD_KEYPAD_KEYPAD_NUM_LOCK_AND_CLEAR)
{
/* NUM LOCK pressed */ //NUM_LOCK反転
if(appData.numLockPressed == false)
{
appData.numLockPressed = true;
outputReport = outputReport | 0x1; //b0 = 1 にセット
}
else
{
appData.numLockPressed = false;
outputReport = outputReport & 0xFE; //b0 = 0 にリセット
}
}

//キーシフト有無判別
if(appData.capsLockPressed || //キャップスキーが押されている場合
appData.data.modifierKeysData.leftShift || //左シフトキーが押されている場合
appData.data.modifierKeysData.rightShift) //右シフトキーが押されている場合
ys_Shift_MapKey(keyCode, outputReport); //シフトモードのキーマップ関数
else ys_NonShift_MapKey(keyCode, outputReport); //非シフトモードのキーマップ関数


switch(keyCode) //シフト/非シフトに無関係なキー
{
case USB_HID_KEYBOARD_KEYPAD_KEYBOARD_ESCAPE: //0x29 //エスケープ Esc
ys_Function_0xXX(keyCode, moji_Esc); break;
case USB_HID_KEYBOARD_KEYPAD_KEYBOARD_RETURN_ENTER: //0x28 //エンター Enter
ys_Function_Enter(keyCode); break;
case USB_HID_KEYBOARD_KEYPAD_KEYBOARD_DELETE: //0x2A //バックスペース Back Space
ys_Function_0xXX(keyCode, moji_BackSpace); break;
case USB_HID_KEYBOARD_KEYPAD_KEYBOARD_CAPS_LOCK: //0x39 //キャップスロック Caps Lock
ys_Function_0xXX(keyCode, moji_CapsLock); break;
case USB_HID_KEYBOARD_KEYPAD_KEYBOARD_PRINT_SCREEN: //0x46 //プリントスクリーン Print Screen
ys_Function_0xXX(keyCode, moji_PrintScreen); break;
case USB_HID_KEYBOARD_KEYPAD_KEYBOARD_SCROLL_LOCK: //0x47 //スクロールロック Scroll Lock
ys_Function_0xXX(keyCode, moji_ScrollLock); break;
case USB_HID_KEYBOARD_KEYPAD_KEYBOARD_PAUSE: //0x48 //ポーズ/ブレイク Pause/Break
ys_Function_0xXX(keyCode, moji_PauseBreak); break;
case USB_HID_KEYBOARD_KEYPAD_KEYBOARD_INSERT: //0x49 //インサート Insert
ys_Function_0xXX(keyCode, moji_Insert); break;
case USB_HID_KEYBOARD_KEYPAD_KEYBOARD_HOME: //0x4A //ホーム Home
ys_Function_0xXX(keyCode, moji_Home); break;
case USB_HID_KEYBOARD_KEYPAD_KEYBOARD_PAGE_UP: //0x4B //ページアップ Page Up
ys_Function_0xXX(keyCode, moji_PageUp); break;
case USB_HID_KEYBOARD_KEYPAD_KEYBOARD_DELETE_FORWARD: //0x4C //デリート Delete
ys_Function_0xXX(keyCode, moji_Delete); break;
case USB_HID_KEYBOARD_KEYPAD_KEYBOARD_END: //0x4D //エンド End
ys_Function_0xXX(keyCode, moji_End); break;
case USB_HID_KEYBOARD_KEYPAD_KEYBOARD_PAGE_DOWN: //0x4E //ページダウン Page Down
ys_Function_0xXX(keyCode, moji_PageDown); break;
case USB_HID_KEYBOARD_KEYPAD_KEYBOARD_RIGHT_ARROW: //0x4F //右向き矢印 →
ys_Function_0xXX(keyCode, moji_ArrowRight); break;
case USB_HID_KEYBOARD_KEYPAD_KEYBOARD_LEFT_ARROW: //0x50 //左向き矢印 ←
ys_Function_0xXX(keyCode, moji_ArrowLeft); break;
case USB_HID_KEYBOARD_KEYPAD_KEYBOARD_DOWN_ARROW: //0x51 //下向き矢印 ↓
ys_Function_0xXX(keyCode, moji_ArrowDown); break;
case USB_HID_KEYBOARD_KEYPAD_KEYBOARD_UP_ARROW: //0x52 //上向き矢印 ↑
ys_Function_0xXX(keyCode, moji_ArrowUp); break;
case USB_HID_KEYBOARD_KEYPAD_KEYPAD_NUM_LOCK_AND_CLEAR: //0x53 //数字キーロック Num Lock
ys_Function_0xXX(keyCode, moji_NumLock); break;
case USB_HID_KEYBOARD_KEYPAD_KEYBOARD_SPACEBAR: //0x2C //スペースバー
ys_Char_0xXX(keyCode, ' '); break;
case 0x35: //半角/全角 漢字
ys_Function_0xXX(keyCode, moji_Kanji); break;
case 0xFFFFFF8B : //無変換
ys_Function_0xFFFF(keyCode, moji_MuHenkan); break;
case 0xFFFFFF8A: //変換
ys_Function_0xFFFF(keyCode, moji_Henkan); break;
case 0xFFFFFF88: //カタカナ ひらがな ローマ字
ys_Function_0xFFFF(keyCode, moji_Katakana); break;
case 0x65: //Menu (図記号)
ys_Function_0xXX(keyCode, moji_Menu); break;
case USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F1: //0x3A //F1
ys_Function_0xXX(keyCode, moji_F1); break;
case USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F2: //0x3B //F2
ys_Function_0xXX(keyCode, moji_F2); break;
case USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F3: //0x3C //F3
ys_Function_0xXX(keyCode, moji_F3); break;
case USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F4: //0x3D //F4
ys_Function_0xXX(keyCode, moji_F4); break;
case USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F5: //0x3E //F5
ys_Function_0xXX(keyCode, moji_F5); break;
case USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F6: //0x3F //F6
ys_Function_0xXX(keyCode, moji_F6); break;
case USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F7: //0x40 //F7
ys_Function_0xXX(keyCode, moji_F7); break;
case USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F8: //0x41 //F8
ys_Function_0xXX(keyCode, moji_F8); break;
case USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F9: //0x42 //F9
ys_Function_0xXX(keyCode, moji_F9); break;
case USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F10: //0x43 //F10
ys_Function_0xXX(keyCode, moji_F10); break;
case USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F11: //0x45 //F11
ys_Function_0xXX(keyCode, moji_F11); break;
case USB_HID_KEYBOARD_KEYPAD_KEYBOARD_F12: //0x46 //F12
ys_Function_0xXX(keyCode, moji_F12); break;
default: break;
}

appData.currentOffset = appData.currentOffset + sizeof(keyValue[keyCode]);
//APP_TASKS()が1巡する間に複数回打鍵が行われた場合、appData.string[64]に複数個のキーデータを保持


}

// *****************************************************************************
// *****************************************************************************
// Section: Application Initialization and State Machine Functions
// *****************************************************************************
// *****************************************************************************

/*******************************************************************************
Function:
void APP_Initialize ( void )

Remarks:
See prototype in app.h.
*/

void APP_Initialize ( void )
{
/* Place the App state machine in its initial state. */
memset(&appData, 0, sizeof(appData));
appData.state = APP_STATE_INIT;
appData.usartTaskState = APP_USART_STATE_DRIVER_OPEN;



lcd_ACM1602_init_i2c(); //I2Cインターフェース式液晶初期化
lcd_ACM1602_cmd_i2c(0x0C); //カーソル:0FF、ブリンク:0FF

lcd_ACM1602_cmd_i2c(0x80); //1行目の先頭へ
lcd_ACM1602_str_i2c("USB device HID ");

delay_ms(1000);

lcd_ACM1602_cmd_i2c(0xC0); //2行目の先頭へ
lcd_ACM1602_str_i2c(" Keyboard demo ");

delay_ms(2000);

}


void APP_USART_Tasks(void)
{
switch(appData.usartTaskState)
{
case APP_USART_STATE_DRIVER_OPEN:

/* Try to open the USART driver */
appData.usartDriverHandle = DRV_USART_Open(DRV_USART_INDEX_0,
DRV_IO_INTENT_READWRITE | DRV_IO_INTENT_NONBLOCKING);
if(appData.usartDriverHandle != DRV_HANDLE_INVALID)
{
/* The driver could be opened. We should be able to send data */
appData.usartTaskState = APP_USART_STATE_CHECK_FOR_STRING_TO_SEND;
}
break;

case APP_USART_STATE_CHECK_FOR_STRING_TO_SEND:

/* In this state we check if the there is string to be transmitted */
if(appData.stringReady)
{
/* Write the string to the driver */
appData.usartTaskState = APP_USART_STATE_DRIVER_WRITE;
appData.nBytesWritten = 0;
}

break;

case APP_USART_STATE_DRIVER_WRITE:

/* Write the string to the driver. We will need to check how much
* of the string was actually written and update the pointer and
* size accordingly */
//UARTドライバに送信
appData.nBytesWritten += DRV_USART_Write(appData.usartDriverHandle,
appData.string + appData.nBytesWritten, appData.stringSize - appData.nBytesWritten);

if(appData.nBytesWritten >= appData.stringSize)
{
/* This means all the data was written. Clear the flag
* so the application know we are done. Change the state
* to continue check if another string needs to be
* sent. */

appData.stringReady = false;
appData.usartTaskState = APP_USART_STATE_CHECK_FOR_STRING_TO_SEND;
}
break;

default:
break;
}
}

/******************************************************************************
Function:
void APP_Tasks ( void )

Remarks:
See prototype in app.h.
*/

void APP_Tasks ( void )
{
uint64_t sysCount = 0;
uint8_t count = 0;
uint8_t counter = 0;
bool foundInLast = false; //最後の検出

appData.currentOffset = 0;

/* Check the application's current state. */
switch ( appData.state )
{
/* Application's initial state. */
case APP_STATE_INIT:
USB_HOST_EventHandlerSet(APP_USBHostEventHandler, 0);
USB_HOST_HID_KEYBOARD_EventHandlerSet(APP_USBHostHIDKeyboardEventHandler);

USB_HOST_BusEnable(0);
appData.state = APP_STATE_WAIT_FOR_HOST_ENABLE;
break;

case APP_STATE_WAIT_FOR_HOST_ENABLE:
/* Check if the host operation has been enabled */
if(USB_HOST_BusIsEnabled(0))
{
/* This means host operation is enabled. We can
* move on to the next state */
appData.state = APP_STATE_HOST_ENABLE_DONE;
}
break;
case APP_STATE_HOST_ENABLE_DONE:
appData.stringSize = 64;
if(appData.usartTaskState == APP_USART_STATE_CHECK_FOR_STRING_TO_SEND)
{
memcpy(&appData.string[0], "\r\n***Connect Keyboard***\r\n",
sizeof("\r\n***Connect Keyboard***\r\n"));


lcd_ACM1602_cmd_i2c(0x80); //1行目の先頭へ
lcd_ACM1602_str_i2c("Please Connect ");

lcd_ACM1602_cmd_i2c(0xC0); //2行目の先頭へ
lcd_ACM1602_str_i2c(" Keyboard !! ");



appData.stringReady = true;
/* The test was successful. Lets idle. */
appData.state = APP_STATE_WAIT_FOR_DEVICE_ATTACH;
}
break;

case APP_STATE_WAIT_FOR_DEVICE_ATTACH:

/* Wait for device attach. The state machine will move
* to the next state when the attach event
* is received. */

break;

case APP_STATE_DEVICE_ATTACHED:

/* Wait for device report */
if(appData.usartTaskState == APP_USART_STATE_CHECK_FOR_STRING_TO_SEND)
{
memcpy(&appData.string[0], "---Keyboard Connected---\r\n",
sizeof("---Keyboard Connected---\r\n"));

lcd_ACM1602_cmd_i2c(0x80); //1行目の先頭へ
lcd_ACM1602_str_i2c("Keyboard has ");

lcd_ACM1602_cmd_i2c(0xC0); //2行目の先頭へ
lcd_ACM1602_str_i2c(" Connected ");


appData.stringReady = true;
appData.stringSize = 64;
appData.state = APP_STATE_READ_HID;
}
break;

case APP_STATE_READ_HID:
appData.stringReady = false;
if(appData.usartTaskState == APP_USART_STATE_CHECK_FOR_STRING_TO_SEND)
{
/* We can send Data to USART but need to check*/
appData.stringSize = 64;
memset(&appData.string, 0, sizeof(appData.string));

/* We need to display only the non modifier keys */
for(count = 0; count < 6; count++)
{
if(appData.data.nonModifierKeysData[count].event == USB_HID_KEY_PRESSED)
{
for(counter = 0; counter < 6; counter++)
{
if((appData.lastData.data.nonModifierKeysData[counter].event == USB_HID_KEY_PRESSED)
&&((appData.lastData.data.nonModifierKeysData[counter].keyCode ==
appData.data.nonModifierKeysData[count].keyCode)))
{
sysCount = SYS_TMR_SystemCountGet ();
if(200 <= 1000 *
(sysCount - appData.lastData.data.nonModifierKeysData[counter].sysCount)
/ SYS_TMR_SystemCountFrequencyGet())
{
foundInLast = false;
}
else
{
foundInLast = true;
}
break;
}
}
if(foundInLast == false)
{
appData.stringReady = true;
APP_MapKeyToUsage(appData.data.nonModifierKeysData[count].keyCode);
}
else
{
/* Reset it it false for next iteration */
foundInLast = false;
}
}
}
/* Store the present to future */
memcpy(&appData.lastData.data, &appData.data, sizeof(appData.data));
}
break;

case APP_STATE_DEVICE_DETACHED:
appData.state = APP_STATE_HOST_ENABLE_DONE;
break;

case APP_STATE_ERROR:

/* The application comes here when the demo
* has failed. Provide LED indication .*/

// BSP_LEDOn( APP_USB_LED_1 );
break;

default:
break;
}
/* Call the USART task routine */
APP_USART_Tasks(); //UART]側に送信

}


/*******************************************************************************
End of File
*/